#include "nr_nport_net_connector.h"



nr_nport_net_connector::nr_nport_net_connector()
	: m_thread_quit(false)
	, m_port(-1)
	, m_connect_timeout(5000)
	, m_write_timeout(3000)
	, m_read_timeout(3000)
{
	//m_host = this->device
}

void nr_nport_net_connector::run()
{
#ifdef NR_NPORT_USE_SAMPLE_DATA 
    return ; // Do not connect to the real device if using sample data
#endif

    m_tcp_socket = new QTcpSocket();

	// Try to connect to the nport device here
	// Note : should consider the condition when device connect failed,
	// Auto reconnect ? or report a failed status?

	m_tcp_socket->connectToHost(m_host,m_port);
	////m_tcp_socket->connectToHost("192.168.1.254",254);
	bool ret=m_tcp_socket->waitForConnected(5000);

	Q_ASSERT(ret);


	while(!m_thread_quit)
	{
		// Lock the queue before we do any operation with the queue
		m_queue_lock.lock();

		// Wait until we get one packet
		if(m_command_queue.empty())
		{
			// This wait condition may wakened up by the 
			// push_command() or stop()             
			m_queue_wait_condition.wait(&m_queue_lock);
		}

		// Judge the flag again, the wait condition may be set
		// by the stop function
		if (m_thread_quit)
		{
			m_queue_lock.unlock();
			break;
		}

		//// Try to get one command from the queue
		//nr_device_command_base* cmd = m_command_queue.dequeue();
		//Q_ASSERT(cmd);

		nr_device_commandlist_base* cmdlist = m_commandlist_queue.dequeue();
		Q_ASSERT(cmdlist);

		//// Unlock the queue here, because the other operation does not use 
		//// the queue and other thread can add more commands at the same time
		m_queue_lock.unlock();

		//// OK, we can process the command here
		//process_command(cmd);
		process_commandlist(cmdlist);
		
		//// Destroy the command
		//delete cmd;
		delete cmdlist;

	}

	// m_timer = new QTimer();

	// m_timer->start(5000);

	// bool ret = connect(m_timer, SIGNAL(timeout()), this, SLOT(on_timeout()));
	// Q_ASSERT(ret);

	// Start the event loop here, so the QTcpSocket and QTimer can use in this thread
	// this->exec();

	// Release all the sockets and timer objects
	// m_timer->stop();

	// delete m_timer;

	m_tcp_socket->disconnectFromHost();
	m_tcp_socket->waitForDisconnected(1000);

	// Destroy the socket anyway
	delete m_tcp_socket;
}


void nr_nport_net_connector::push_command(nr_device_command_base *cmd)
{
	Q_ASSERT(cmd);

	// Auto lock the queue before we write data to it
	QMutexLocker locker(&m_queue_lock);

	// Push the command to the command queue
	m_command_queue.enqueue(cmd);

	// Wake some one who is waiting for the queue
	m_queue_wait_condition.wakeOne();
}

void nr_nport_net_connector::push_commandlist(nr_device_commandlist_base *cmdlist)
{
	Q_ASSERT(cmdlist);

	// Auto lock the queue before we write data to it
	QMutexLocker locker(&m_queue_lock);

	// Push the commands to the command queue
	m_commandlist_queue.enqueue(cmdlist);

	// Wake some one who is waiting for the queue
	m_queue_wait_condition.wakeOne();

}



void nr_nport_net_connector::process_commandlist(nr_device_commandlist_base *cmdlist)
{
	nr_device_command_deletegate* cmd_delegate = cmdlist->delegate();

	if(cmd_delegate)
		cmd_delegate->on_deal_commanlist(*m_tcp_socket,&(cmdlist->commandstrlist()), &(cmdlist->commandlist()));

}